home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / DELPHI / SPIN.ZIP / SPIN.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-10-31  |  16.8 KB  |  645 lines

  1. unit Spin;
  2.  
  3. interface
  4.  
  5. uses WinTypes, Classes, StdCtrls, ExtCtrls, Controls, Messages, SysUtils,
  6.   Forms, Graphics, Menus, Buttons;
  7.  
  8. const
  9.   InitRepeatPause = 400;  { pause before repeat timer (ms) }
  10.   RepeatPause     = 100;  { pause before hint window displays (ms)}
  11.  
  12. type
  13.  
  14.   TTimerSpeedButton = class;
  15.  
  16. { TSpinButton }
  17.  
  18.   TSpinButton = class (TWinControl)
  19.   private
  20.     FUpButton: TTimerSpeedButton;
  21.     FDownButton: TTimerSpeedButton;
  22.     FFocusedButton: TTimerSpeedButton;
  23.     FFocusControl: TWinControl;
  24.     FOnUpClick: TNotifyEvent;
  25.     FOnDownClick: TNotifyEvent;
  26.     FVerticalPositioning : Boolean;
  27.     function CreateButton: TTimerSpeedButton;
  28.     function GetUpGlyph: TBitmap;
  29.     function GetDownGlyph: TBitmap;
  30.     procedure SetUpGlyph(Value: TBitmap);
  31.     procedure SetDownGlyph(Value: TBitmap);
  32.     procedure BtnClick(Sender: TObject);
  33.     procedure BtnMouseDown (Sender: TObject; Button: TMouseButton;
  34.       Shift: TShiftState; X, Y: Integer);
  35.     procedure SetFocusBtn (Btn: TTimerSpeedButton);
  36.     procedure AdjustSize (var W: Integer; var H: Integer);
  37.     function GetPositioning : boolean;
  38.     procedure SetPositioning(Vertical:boolean);
  39.     function GetDownButtonState : boolean;
  40.     procedure SetDownButtonState(NewState:boolean);
  41.     function GetUpButtonState : boolean;
  42.     procedure SetUpButtonState(NewState:boolean);
  43.     procedure WMSize(var Message: TWMSize);  message WM_SIZE;
  44.     procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  45.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  46.     procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  47.   protected
  48.     procedure Loaded; override;
  49.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  50.   public
  51.     constructor Create(AOwner: TComponent); override;
  52.     procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  53.   published
  54.     property Align;
  55.     property Ctl3D;
  56.     property DownGlyph: TBitmap read GetDownGlyph write SetDownGlyph;
  57.     property DownButtonEnabled : boolean read GetDownButtonState write SetDownButtonState default True;
  58.     property DragCursor;
  59.     property DragMode;
  60.     property Enabled;
  61.     property FocusControl: TWinControl read FFocusControl write FFocusControl;
  62.     property ParentCtl3D;
  63.     property ParentShowHint;
  64.     property PopupMenu;
  65.     property ShowHint;
  66.     property TabOrder;
  67.     property TabStop;
  68.     property UpGlyph: TBitmap read GetUpGlyph write SetUpGlyph;
  69.     property Visible;
  70.     property OnDownClick: TNotifyEvent read FOnDownClick write FOnDownClick;
  71.     property OnDragDrop;
  72.     property OnDragOver;
  73.     property OnEndDrag;
  74.     property OnEnter;
  75.     property OnExit;
  76.     property OnUpClick: TNotifyEvent read FOnUpClick write FOnUpClick;
  77.     property UpButtonEnabled : boolean read GetUpButtonState write SetUpButtonState default True;
  78.     property Vertical : Boolean read GetPositioning write SetPositioning default True;
  79.   end;
  80.  
  81. { TSpinEdit }
  82.  
  83.   TSpinEdit = class(TCustomEdit)
  84.   private
  85.     FMinValue: LongInt;
  86.     FMaxValue: LongInt;
  87.     FCanvas: TCanvas;
  88.     FIncrement: LongInt;
  89.     FButton: TSpinButton;
  90.     FEditorEnabled: Boolean;
  91.     function GetMinHeight: Integer;
  92.     function GetValue: LongInt;
  93.     function CheckValue (NewValue: LongInt): LongInt;
  94.     procedure SetValue (NewValue: LongInt);
  95.     procedure SetEditRect;
  96.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  97.     procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;
  98.     procedure CMExit(var Message: TCMExit);   message CM_EXIT;
  99.     procedure WMPaste(var Message: TWMPaste);   message WM_PASTE;
  100.     procedure WMCut(var Message: TWMCut);   message WM_CUT;
  101.   protected
  102.     function IsValidChar(Key: Char): Boolean; virtual;
  103.     procedure UpClick (Sender: TObject); virtual;
  104.     procedure DownClick (Sender: TObject); virtual;
  105.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  106.     procedure KeyPress(var Key: Char); override;
  107.     procedure CreateParams(var Params: TCreateParams); override;
  108.     procedure CreateWnd; override;
  109.   public
  110.     constructor Create(AOwner: TComponent); override;
  111.     destructor Destroy; override;
  112.     property Button: TSpinButton read FButton;
  113.   published
  114.     property AutoSelect;
  115.     property AutoSize;
  116.     property Color;
  117.     property Ctl3D;
  118.     property DragCursor;
  119.     property DragMode;
  120.     property EditorEnabled: Boolean read FEditorEnabled write FEditorEnabled default True;
  121.     property Enabled;
  122.     property Font;
  123.     property Increment: LongInt read FIncrement write FIncrement default 1;
  124.     property MaxLength;
  125.     property MaxValue: LongInt read FMaxValue write FMaxValue;
  126.     property MinValue: LongInt read FMinValue write FMinValue;
  127.     property ParentColor;
  128.     property ParentCtl3D;
  129.     property ParentFont;
  130.     property ParentShowHint;
  131.     property PopupMenu;
  132.     property ReadOnly;
  133.     property ShowHint;
  134.     property TabOrder;
  135.     property TabStop;
  136.     property Value: LongInt read GetValue write SetValue;
  137.     property Visible;
  138.     property OnChange;
  139.     property OnClick;
  140.     property OnDblClick;
  141.     property OnDragDrop;
  142.     property OnDragOver;
  143.     property OnEndDrag;
  144.     property OnEnter;
  145.     property OnExit;
  146.     property OnKeyDown;
  147.     property OnKeyPress;
  148.     property OnKeyUp;
  149.     property OnMouseDown;
  150.     property OnMouseMove;
  151.     property OnMouseUp;
  152.   end;
  153.  
  154. { TTimerSpeedButton }
  155.  
  156.   TTimeBtnState = set of (tbFocusRect, tbAllowTimer);
  157.  
  158.   TTimerSpeedButton = class(TSpeedButton)
  159.   private
  160.     FRepeatTimer: TTimer;
  161.     FTimeBtnState: TTimeBtnState;
  162.     procedure TimerExpired(Sender: TObject);
  163.   protected
  164.     procedure Paint; override;
  165.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  166.       X, Y: Integer); override;
  167.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  168.       X, Y: Integer); override;
  169.   public
  170.     destructor Destroy; override;
  171.     property TimeBtnState: TTimeBtnState read FTimeBtnState write FTimeBtnState;
  172.   end;
  173.  
  174. implementation
  175.  
  176. uses WinProcs;
  177.  
  178. {$R SPIN}
  179.  
  180. { TSpinButton }
  181.  
  182. constructor TSpinButton.Create(AOwner: TComponent);
  183. begin
  184.   inherited Create(AOwner);
  185.   ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] +
  186.     [csFramed, csOpaque];
  187.  
  188.   FUpButton := CreateButton;
  189.   FDownButton := CreateButton;
  190.   UpGlyph := nil;
  191.   DownGlyph := nil;
  192.  
  193.   Width := 20;
  194.   Height := 25;
  195.   FFocusedButton := FUpButton;
  196.   FVerticalPositioning := True;
  197. end;
  198.  
  199. function TSpinButton.CreateButton: TTimerSpeedButton;
  200. begin
  201.   Result := TTimerSpeedButton.Create (Self);
  202.   Result.OnClick := BtnClick;
  203.   Result.OnMouseDown := BtnMouseDown;
  204.   Result.Visible := True;
  205.   Result.Enabled := True;
  206.   Result.TimeBtnState := [tbAllowTimer];
  207.   Result.NumGlyphs := 1;
  208.   Result.Parent := Self;
  209. end;
  210.  
  211. procedure TSpinButton.AdjustSize (var W: Integer; var H: Integer);
  212. var
  213.   Y: Integer;
  214. begin
  215.   if (FUpButton = nil) or (csLoading in ComponentState) then Exit;
  216.   if W < 15 then W := 15;
  217.   if FVerticalPositioning then begin
  218.     FUpButton.SetBounds (0, 0, W, H div 2);
  219.     FDownButton.SetBounds (0, FUpButton.Height - 1, W, H - FUpButton.Height + 1);
  220.   end else begin
  221.     FUpButton.SetBounds (0, 0, W div 2, H);
  222.     FDownButton.SetBounds (FUpButton.Width, 0, W div 2, H);
  223.   end;
  224. end;
  225.  
  226. procedure TSpinButton.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
  227. var
  228.   W, H: Integer;
  229. begin
  230.   W := AWidth;
  231.   H := AHeight;
  232.   AdjustSize (W, H);
  233.   inherited SetBounds (ALeft, ATop, W, H);
  234. end;
  235.  
  236. procedure TSpinButton.WMSize(var Message: TWMSize);
  237. var
  238.   W, H: Integer;
  239. begin
  240.   inherited;
  241.  
  242.   { check for minimum size }
  243.   W := Width;
  244.   H := Height;
  245.   AdjustSize (W, H);
  246.   if (W <> Width) or (H <> Height) then
  247.     inherited SetBounds(Left, Top, W, H);
  248.   Message.Result := 0;
  249. end;
  250.  
  251. procedure TSpinButton.WMSetFocus(var Message: TWMSetFocus);
  252. begin
  253.   FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState + [tbFocusRect];
  254.   FFocusedButton.Invalidate;
  255. end;
  256.  
  257. procedure TSpinButton.WMKillFocus(var Message: TWMKillFocus);
  258. begin
  259.   FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState - [tbFocusRect];
  260.   FFocusedButton.Invalidate;
  261. end;
  262.  
  263. procedure TSpinButton.KeyDown(var Key: Word; Shift: TShiftState);
  264. begin
  265.   case Key of
  266.     VK_UP:
  267.       begin
  268.         SetFocusBtn (FUpButton);
  269.         FUpButton.Click;
  270.       end;
  271.     VK_DOWN:
  272.       begin
  273.         SetFocusBtn (FDownButton);
  274.         FDownButton.Click;
  275.       end;
  276.     VK_SPACE:
  277.       FFocusedButton.Click;
  278.   end;
  279. end;
  280.  
  281. procedure TSpinButton.BtnMouseDown (Sender: TObject; Button: TMouseButton;
  282.   Shift: TShiftState; X, Y: Integer);
  283. begin
  284.   if Button = mbLeft then
  285.   begin
  286.     SetFocusBtn (TTimerSpeedButton (Sender));
  287.     if (FFocusControl <> nil) and FFocusControl.TabStop and 
  288.         FFocusControl.CanFocus and (GetFocus <> FFocusControl.Handle) then
  289.       FFocusControl.SetFocus
  290.     else if TabStop and (GetFocus <> Handle) and CanFocus then
  291.       SetFocus;
  292.   end;
  293. end;
  294.  
  295. procedure TSpinButton.BtnClick(Sender: TObject);
  296. begin
  297.   if Sender = FUpButton then
  298.   begin
  299.     if Assigned(FOnUpClick) then FOnUpClick(Self);
  300.   end
  301.   else
  302.     if Assigned(FOnDownClick) then FOnDownClick(Self);
  303. end;
  304.  
  305. procedure TSpinButton.SetFocusBtn (Btn: TTimerSpeedButton);
  306. begin
  307.   if TabStop and CanFocus and  (Btn <> FFocusedButton) then
  308.   begin
  309.     FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState - [tbFocusRect];
  310.     FFocusedButton := Btn;
  311.     if (GetFocus = Handle) then 
  312.     begin
  313.        FFocusedButton.TimeBtnState := FFocusedButton.TimeBtnState + [tbFocusRect];
  314.        Invalidate;
  315.     end;
  316.   end;   
  317. end;
  318.  
  319. procedure TSpinButton.WMGetDlgCode(var Message: TWMGetDlgCode);
  320. begin
  321.   Message.Result := DLGC_WANTARROWS;
  322. end;
  323.  
  324. procedure TSpinButton.Loaded;
  325. var
  326.   W, H: Integer;
  327. begin
  328.   inherited Loaded;
  329.   W := Width;
  330.   H := Height;
  331.   AdjustSize (W, H);
  332.   if (W <> Width) or (H <> Height) then
  333.     inherited SetBounds (Left, Top, W, H);
  334. end;
  335.  
  336. function TSpinButton.GetUpGlyph: TBitmap;
  337. begin
  338.   Result := FUpButton.Glyph;
  339. end;
  340.  
  341. procedure TSpinButton.SetUpGlyph(Value: TBitmap);
  342. begin
  343.   if Value <> nil then
  344.     FUpButton.Glyph := Value
  345.   else
  346.   begin
  347.     FUpButton.Glyph.Handle := LoadBitmap(HInstance, 'SpinUp');
  348.     FUpButton.NumGlyphs := 1;
  349.     FUpButton.Invalidate;
  350.   end;
  351. end;
  352.  
  353. function TSpinButton.GetDownGlyph: TBitmap;
  354. begin
  355.   Result := FDownButton.Glyph;
  356. end;
  357.  
  358. procedure TSpinButton.SetDownGlyph(Value: TBitmap);
  359. begin
  360.   if Value <> nil then
  361.     FDownButton.Glyph := Value
  362.   else
  363.   begin
  364.     FDownButton.Glyph.Handle := LoadBitmap(HInstance, 'SpinDown');
  365.     FDownButton.NumGlyphs := 1;
  366.     FDownButton.Invalidate;
  367.   end;
  368. end;
  369.  
  370. { TSpinEdit }
  371.  
  372. constructor TSpinEdit.Create(AOwner: TComponent);
  373. begin
  374.   inherited Create(AOwner);
  375.   FButton := TSpinButton.Create (Self);
  376.   FButton.Width := 15;
  377.   FButton.Height := 17;
  378.   FButton.Visible := True;  
  379.   FButton.Parent := Self;
  380.   FButton.FocusControl := Self;
  381.   FButton.OnUpClick := UpClick;
  382.   FButton.OnDownClick := DownClick;
  383.   Text := '0';
  384.   ControlStyle := ControlStyle - [csSetCaption];
  385.   FIncrement := 1;
  386.   FEditorEnabled := True;
  387. end;
  388.  
  389. destructor TSpinEdit.Destroy;
  390. begin
  391.   FButton := nil;
  392.   inherited Destroy;
  393. end;
  394.  
  395. procedure TSpinEdit.KeyDown(var Key: Word; Shift: TShiftState);
  396. begin
  397.   if Key = VK_UP then UpClick (Self)
  398.   else if Key = VK_DOWN then DownClick (Self);
  399.   inherited KeyDown(Key, Shift);
  400. end;
  401.  
  402. procedure TSpinEdit.KeyPress(var Key: Char);
  403. begin
  404.   if not IsValidChar(Key) then
  405.   begin
  406.     Key := #0;
  407.     MessageBeep(0)
  408.   end;
  409.   if Key <> #0 then inherited KeyPress(Key);
  410. end;
  411.  
  412. function TSpinEdit.IsValidChar(Key: Char): Boolean;
  413. begin
  414.   Result := (Key in [DecimalSeparator, '+', '-', '0'..'9']) or
  415.     ((Key < #32) and (Key <> Chr(VK_RETURN)));
  416.   if not FEditorEnabled and Result and ((Key >= #32) or
  417.       (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE))) then
  418.     Result := False;
  419. end;
  420.  
  421. procedure TSpinEdit.CreateParams(var Params: TCreateParams);
  422. begin
  423.   inherited CreateParams(Params);
  424. {  Params.Style := Params.Style and not WS_BORDER;  }
  425.   Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN;
  426. end;
  427.  
  428. procedure TSpinEdit.CreateWnd;
  429. var
  430.   Loc: TRect;
  431. begin
  432.   inherited CreateWnd;
  433.   SetEditRect;
  434. end;
  435.  
  436. procedure TSpinEdit.SetEditRect;
  437. var
  438.   Loc: TRect;
  439. begin
  440.   SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));
  441.   Loc.Bottom := ClientHeight;
  442.   Loc.Right := ClientWidth - FButton.Width - 2;
  443.   Loc.Top := 0;  
  444.   Loc.Left := 0;  
  445.   SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
  446.   SendMessage(Handle, EM_GETRECT, 0, LongInt(@Loc));  {debug}
  447. end;
  448.  
  449. procedure TSpinEdit.WMSize(var Message: TWMSize);
  450. var
  451.   Loc: TRect;
  452.   MinHeight: Integer;
  453. begin
  454.   inherited;
  455.   MinHeight := GetMinHeight;
  456.     { text edit bug: if size to less than minheight, then edit ctrl does
  457.       not display the text }
  458.   if Height < MinHeight then   
  459.     Height := MinHeight
  460.   else if FButton <> nil then
  461.   begin
  462.     FButton.SetBounds (Width - FButton.Width, 0, FButton.Width, Height);  
  463.     SetEditRect;
  464.   end;
  465. end;
  466.  
  467. function TSpinEdit.GetMinHeight: Integer;
  468. var
  469.   DC: HDC;
  470.   SaveFont: HFont;
  471.   I: Integer;
  472.   SysMetrics, Metrics: TTextMetric;
  473. begin
  474.   DC := GetDC(0);
  475.   GetTextMetrics(DC, SysMetrics);
  476.   SaveFont := SelectObject(DC, Font.Handle);
  477.   GetTextMetrics(DC, Metrics);
  478.   SelectObject(DC, SaveFont);
  479.   ReleaseDC(0, DC);
  480.   I := SysMetrics.tmHeight;
  481.   if I > Metrics.tmHeight then I := Metrics.tmHeight;
  482.   Result := Metrics.tmHeight + I div 4 + GetSystemMetrics(SM_CYBORDER) * 4 + 2;
  483. end;
  484.  
  485. procedure TSpinEdit.UpClick (Sender: TObject);
  486. begin
  487.   if ReadOnly then MessageBeep(0)
  488.   else Value := Value + FIncrement;
  489. end;
  490.  
  491. procedure TSpinEdit.DownClick (Sender: TObject);
  492. begin
  493.   if ReadOnly then MessageBeep(0)
  494.   else Value := Value - FIncrement;
  495. end;
  496.  
  497. procedure TSpinEdit.WMPaste(var Message: TWMPaste);   
  498. begin
  499.   if not FEditorEnabled or ReadOnly then Exit;
  500.   inherited;
  501. end;
  502.  
  503. procedure TSpinEdit.WMCut(var Message: TWMPaste);   
  504. begin
  505.   if not FEditorEnabled or ReadOnly then Exit;
  506.   inherited;
  507. end;
  508.  
  509. procedure TSpinEdit.CMExit(var Message: TCMExit);
  510. begin
  511.   inherited;
  512.   if CheckValue (Value) <> Value then
  513.     SetValue (Value);
  514. end;
  515.  
  516. function TSpinEdit.GetValue: LongInt;
  517. begin
  518.   try
  519.     Result := StrToInt (Text);
  520.   except
  521.     Result := FMinValue;
  522.   end;
  523. end;
  524.  
  525. procedure TSpinEdit.SetValue (NewValue: LongInt);
  526. begin
  527.   Text := IntToStr (CheckValue (NewValue));
  528. end;
  529.  
  530. function TSpinEdit.CheckValue (NewValue: LongInt): LongInt;
  531. begin
  532.   Result := NewValue;
  533.   if (FMaxValue <> FMinValue) then
  534.   begin
  535.     if NewValue < FMinValue then
  536.       Result := FMinValue
  537.     else if NewValue > FMaxValue then
  538.       Result := FMaxValue;
  539.   end;
  540. end;
  541.  
  542. procedure TSpinEdit.CMEnter(var Message: TCMGotFocus);
  543. begin
  544.   if AutoSelect and not (csLButtonDown in ControlState) then
  545.     SelectAll;
  546.   inherited;
  547. end;
  548.  
  549. {TTimerSpeedButton}
  550.  
  551. destructor TTimerSpeedButton.Destroy;
  552. begin
  553.   if FRepeatTimer <> nil then
  554.     FRepeatTimer.Free;
  555.   inherited Destroy;
  556. end;
  557.  
  558. procedure TTimerSpeedButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  559.   X, Y: Integer);
  560. begin
  561.   inherited MouseDown (Button, Shift, X, Y);
  562.   if tbAllowTimer in FTimeBtnState then
  563.   begin
  564.     if FRepeatTimer = nil then
  565.       FRepeatTimer := TTimer.Create(Self);
  566.  
  567.     FRepeatTimer.OnTimer := TimerExpired;
  568.     FRepeatTimer.Interval := InitRepeatPause;
  569.     FRepeatTimer.Enabled  := True;
  570.   end;
  571. end;
  572.  
  573. procedure TTimerSpeedButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
  574.                                   X, Y: Integer);
  575. begin
  576.   inherited MouseUp (Button, Shift, X, Y);
  577.   if FRepeatTimer <> nil then
  578.     FRepeatTimer.Enabled  := False;
  579. end;
  580.  
  581. procedure TTimerSpeedButton.TimerExpired(Sender: TObject);
  582. begin
  583.   FRepeatTimer.Interval := RepeatPause;
  584.   if (FState = bsDown) and MouseCapture then
  585.   begin
  586.     try
  587.       Click;
  588.     except
  589.       FRepeatTimer.Enabled := False;
  590.       raise;
  591.     end;
  592.   end;
  593. end;
  594.  
  595. procedure TTimerSpeedButton.Paint;
  596. var
  597.   R: TRect;
  598. begin
  599.   inherited Paint;
  600.   if tbFocusRect in FTimeBtnState then
  601.   begin
  602.     R := Bounds(0, 0, Width, Height);
  603.     InflateRect(R, -3, -3);
  604.     if FState = bsDown then
  605.       OffsetRect(R, 1, 1);
  606.     DrawFocusRect(Canvas.Handle, R);
  607.   end;
  608. end;
  609.  
  610. function TSpinButton.GetPositioning;
  611. begin
  612.   Result := FVerticalPositioning;
  613. end;
  614.  
  615. procedure TSpinButton.SetPositioning;
  616. begin
  617.   FVerticalPositioning := Vertical;
  618.   SetBounds(Left,Top,Width,Height);
  619. end;
  620.  
  621. function TSpinButton.GetDownButtonState;
  622. begin
  623.   Result := FDownButton.Enabled;
  624. end;
  625.  
  626. procedure TSpinButton.SetDownButtonState(NewState:boolean);
  627. begin
  628.   FDownButton.Enabled := NewState;
  629.   FDownButton.Repaint;
  630. end;
  631.  
  632. function TSpinButton.GetUpButtonState;
  633. begin
  634.   Result := FUpButton.Enabled;
  635. end;
  636.  
  637. procedure TSpinButton.SetUpButtonState(NewState:boolean);
  638. begin
  639.   FUpButton.Enabled := NewState;
  640.   FUpButton.Repaint;
  641. end;
  642.  
  643. end.
  644.  
  645.